package cn.jtool.dig.client;

import cn.jtool.dig.client.comm.VirtualManager;
import cn.jtool.dig.common.metrics.MetricManager;
import cn.jtool.dig.common.metrics.MetricMeta;
import cn.jtool.dig.common.netty.TcpClient;
import cn.jtool.dig.common.util.SpringContextUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Import;
import org.springframework.scheduling.annotation.EnableScheduling;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Slf4j
@EnableScheduling
@SpringBootApplication
@Import({
        SpringContextUtil.class
})
//@ComponentScan(basePackages = "com.kunlunbd.component.relay")
public class Application implements CommandLineRunner {

    @Value("${metrics.interval:60}")
    private int metricsInterval;

    static Date serverStartTime;

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
        log.info("service is started......");
        serverStartTime = new Date();

    }

    @Override
    public void run(String... args) {
        try {
            //startMetrics();
        }catch (Exception ignored){

        }
    }

    public void startMetrics(){
        Thread statThread = new Thread(() -> {
            while(true){
                Logger statLog = LoggerFactory.getLogger("STAT");
                try {
                    TimeUnit.SECONDS.sleep(this.metricsInterval);
                    TcpClient relayClient = (TcpClient) SpringContextUtil.getBean("relayClient");
                    List<TcpClient> tcpClients = VirtualManager.getClient();

                        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        statLog.info("*******************************************************");
                        statLog.info("当前时间: {}", simpleDateFormat.format(new Date()));
                        statLog.info("系统启动时间: {}", simpleDateFormat.format(serverStartTime));
                        if(!relayClient.isRunning()){
                            statLog.info("Server/Client 链路状态: 断开");
                        }else{
                            statLog.info("Server/Client 链路状态: 正常");
                            statLog.info("Server/Client 链路创建时间: {}", simpleDateFormat.format(relayClient.getConnectTime()));
                        }
                        statLog.info("当前共 [{}] 条链路进行数据转发中", CollectionUtils.isNotEmpty(tcpClients) ? tcpClients.size() : 0);
                        if(CollectionUtils.isNotEmpty(tcpClients)) {
                            tcpClients.sort((o1, o2) -> (int) (o1.getChannelId() - o2.getChannelId()));
                            statLog.info("最小链路ID: {}", tcpClients.get(0).getChannelId());
                            statLog.info("最大链路ID: {}", tcpClients.get(tcpClients.size() - 1).getChannelId());
                        }
                        statLog.info("累计接收数据包数据: {}", MetricManager.getMetric(MetricMeta.receivePacketNumber));
                        statLog.info("累计接收数据包大小: {}", MetricManager.getMetric(MetricMeta.receiveByteSize));
                        statLog.info("累计转发数据包数量: {}", MetricManager.getMetric(MetricMeta.forwardPacketNumber));
                        statLog.info("累计转发数据包大小: {}", MetricManager.getMetric(MetricMeta.forwardByteSize));
                }catch (Exception e){
                    statLog.error("统计报告输出异常", e);
                }
            }
        });
        statThread.setName("stat-metric-thread");
        statThread.start();
    }
}
